﻿using System;
using System.Windows;
using System.Windows.Controls.Primitives;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;

namespace Bookvar.UI.Adorners
{
    public class ResizingAdorner : Adorner
    {
        private readonly Rectangle borderRectangle;
//        private readonly Thumb topLeft;
//        private readonly Thumb topRight;
//        private readonly Thumb bottomLeft;
        private readonly Thumb bottomRight;

        private readonly VisualCollection visualChildren;

        public ResizingAdorner( UIElement adornedElement )
            : base( adornedElement )
        {
            visualChildren = new VisualCollection( this );

            borderRectangle = new Rectangle { Stroke = Brushes.CornflowerBlue };
            visualChildren.Add( borderRectangle );

            // for now we will use only the bottom right due to issues with the rest.
//            BuildAdornerCorner( out topLeft, Cursors.SizeNWSE );
//            BuildAdornerCorner( out topRight, Cursors.SizeNESW );
//            BuildAdornerCorner( out bottomLeft, Cursors.SizeNESW );
            BuildAdornerCorner( out bottomRight, Cursors.SizeNWSE );

//            bottomLeft.DragDelta += HandleBottomLeft;
//            topLeft.DragDelta += HandleTopLeft;
//            topRight.DragDelta += HandleTopRight;
            bottomRight.DragDelta += HandleBottomRight;

            MinWidth = 50;
            MinHeight = 50;
        }

        private void HandleBottomRight( object sender, DragDeltaEventArgs args )
        {
            var adornedElement = AdornedElement as FrameworkElement;
            var hitThumb = sender as Thumb;

            if ( adornedElement == null || hitThumb == null )
            {
                return;
            }

            // Ensure that the Width and Height are properly initialized after the resize.
            EnforceSize( adornedElement );

            adornedElement.Width = Math.Max( adornedElement.Width + args.HorizontalChange, MinWidth );
            adornedElement.Height = Math.Max( args.VerticalChange + adornedElement.Height, MinHeight );
        }

//        private void HandleBottomLeft( object sender, DragDeltaEventArgs args )
//        {
//            var adornedElement = AdornedElement as FrameworkElement;
//            var hitThumb = sender as Thumb;
//
//            if ( adornedElement == null || hitThumb == null )
//            {
//                return;
//            }
//
//            // Ensure that the Width and Height are properly initialized after the resize.
//            EnforceSize( adornedElement );
//
//            Thickness margin = adornedElement.Margin;
//            margin.Left = adornedElement.Margin.Left + args.HorizontalChange;
//            adornedElement.Margin = margin;
//            //adornedElement.Width = Math.Max( adornedElement.Width - args.HorizontalChange, MinWidth );
//            adornedElement.Height = Math.Max( args.VerticalChange + adornedElement.Height, MinHeight );
//        }
//
//        private void HandleTopRight( object sender, DragDeltaEventArgs args )
//        {
//            FrameworkElement adornedElement = AdornedElement as FrameworkElement;
//            Thumb hitThumb = sender as Thumb;
//
//            if ( adornedElement == null || hitThumb == null )
//            {
//                return;
//            }
//
//            // Ensure that the Width and Height are properly initialized after the resize.
//            EnforceSize( adornedElement );
//
//            adornedElement.Width = Math.Max( adornedElement.Width + args.HorizontalChange, MinWidth );
//            adornedElement.Height = Math.Max( adornedElement.Height - args.VerticalChange, MinHeight );
//        }
//
//        private void HandleTopLeft( object sender, DragDeltaEventArgs args )
//        {
//            FrameworkElement adornedElement = AdornedElement as FrameworkElement;
//            Thumb hitThumb = sender as Thumb;
//
//            if ( adornedElement == null || hitThumb == null )
//            {
//                return;
//            }
//
//            // Ensure that the Width and Height are properly initialized after the resize.
//            EnforceSize( adornedElement );
//
//            adornedElement.Width = Math.Max( adornedElement.Width - args.HorizontalChange, MinWidth );
//            adornedElement.Height = Math.Max( adornedElement.Height - args.VerticalChange, MinHeight );
//        }

        protected override Size ArrangeOverride( Size finalSize )
        {
            double adornerWidth = DesiredSize.Width;
            double adornerHeight = DesiredSize.Height;

//            topLeft.Arrange( new Rect( -adornerWidth / 2 - 3, -adornerHeight / 2 - 3, adornerWidth, adornerHeight ) );
//            topRight.Arrange( new Rect( adornerWidth - adornerWidth / 2 + 3, -adornerHeight / 2 - 3, adornerWidth, adornerHeight ) );
//            bottomLeft.Arrange( new Rect( -adornerWidth / 2 - 3, adornerHeight - adornerHeight / 2 + 3, adornerWidth, adornerHeight ) );
            bottomRight.Arrange( new Rect( adornerWidth - adornerWidth / 2 - bottomRight.Width / 2,
                                           adornerHeight - adornerHeight / 2 - bottomRight.Height / 2,
                                           adornerWidth,
                                           adornerHeight ) );

            borderRectangle.Width = adornerWidth + 2;
            borderRectangle.Height = adornerHeight + 2;

            borderRectangle.Arrange( new Rect( -1, -1, adornerWidth + 2, adornerHeight + 2 ) );

            return finalSize;
        }

        private void BuildAdornerCorner( out Thumb cornerThumb, Cursor customizedCursor )
        {
            cornerThumb = new Thumb();
            cornerThumb.Style = FindResource(new ComponentResourceKey(typeof(ResizingAdorner), "ResizeThumb")) as Style;

            // Set some arbitrary visual characteristics.
            cornerThumb.Cursor = customizedCursor;
            cornerThumb.Width = 17;
            cornerThumb.Height = 17;
//
//            cornerThumb.BorderBrush = Brushes.Red;
//            cornerThumb.BorderThickness = new Thickness( 2 );
//            cornerThumb.Background = Brushes.CornflowerBlue;

            visualChildren.Add( cornerThumb );
        }

        private static void EnforceSize( FrameworkElement adornedElement )
        {
            if ( adornedElement.Width.Equals( Double.NaN ) )
            {
                adornedElement.Width = adornedElement.DesiredSize.Width;
            }
            if ( adornedElement.Height.Equals( Double.NaN ) )
            {
                adornedElement.Height = adornedElement.DesiredSize.Height;
            }

            var parent = adornedElement.Parent as FrameworkElement;
            if ( parent != null )
            {
                adornedElement.MaxHeight = parent.ActualHeight;
                adornedElement.MaxWidth = parent.ActualWidth;
            }
        }

        protected override int VisualChildrenCount
        {
            get { return visualChildren.Count; }
        }

        protected override Visual GetVisualChild( int index )
        {
            return visualChildren[ index ];
        }
    }
}